﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace WorkStation.Frameworks.Core.Data
{
    /// <summary>
    /// * 通用查询规格书扩展类
    /// </summary>
    public static class SpecificationExtensions
    {
        /// <summary>
        /// * 与运算
        /// </summary>
        /// <typeparam name="T">参选数据类型</typeparam>
        /// <param name="left">左表达式</param>
        /// <param name="right">右表达式</param>
        /// <returns></returns>
        public static ISpecification<T> And<T>(this ISpecification<T> left, Expression<Func<T, bool>> right) 
        {
            ISpecification<T> rightSpec = new Specification<T>(right);

            return new Specification<T>(v => left.IsSatisfiedBy(v) && rightSpec.IsSatisfiedBy(v));
        }

        /// <summary>
        /// * 或运算
        /// </summary>
        /// <typeparam name="T">参选数据类型</typeparam>
        /// <param name="left">左表达式</param>
        /// <param name="right">右表达式</param>
        /// <returns></returns>
        public static ISpecification<T> Or<T>(this ISpecification<T> left, Expression<Func<T, bool>> right) 
        {
            ISpecification<T> rightSpec = new Specification<T>(right);
            
            return new Specification<T>(v => left.IsSatisfiedBy(v) || rightSpec.IsSatisfiedBy(v));
        }

        /// <summary>
        /// * 非运算
        /// </summary>
        /// <typeparam name="T">参选数据类型</typeparam>
        /// <param name="spec">表达式</param>
        /// <returns></returns>
        public static ISpecification<T> Not<T>(this ISpecification<T> spec) 
        {
            return new Specification<T>(v => !spec.IsSatisfiedBy(v));
        }
    }
}
